using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Net;
using System.Configuration;
using VRCPRServer.Models;
using System.Net.Sockets;
using UnityEngine;
using System.Text.RegularExpressions;
using UnityEngine.Video;
using HHHTool;

namespace VRCPRServer.NetWork
{
    public class NetManger
    {
        public AsyncTcpServer tcpServer;
        public AsyncTcpClient tcpClient;
        public DataBuffer dataBuffer;
        public DataBuffer serverPadDataBuffer;
        #region ipaddress post
       
        string serverIp = "";
        string serverPort = "";
        #endregion
        //public DataBuffer serverDataBuffer;
        /// <summary>
        /// pad连接状态
        /// </summary>
        public event Action<System.Net.Sockets.Socket, bool> PadConnetState;
        /// <summary>
        /// 模拟人接状态
        /// </summary>
        public event Action<IPAddress[], int, bool> BodyConnetState;

        ReadINI readINI = new ReadINI();
        string iniPath = Application.streamingAssetsPath + "/DeviceStatus.ini";
        public NetManger()
        {           
            serverIp = readINI.ReadIPIni("ServerIP", iniPath);
            serverPort = readINI.ReadIPIni("ServerPort", iniPath);
            dataBuffer = new DataBuffer(20480, 9);
            NewServer();        
        }


        public void NewServer()
        {
            if (!IPAddress.TryParse(serverIp, out IPAddress address)) return;
            if (!int.TryParse(serverPort, out int port)) return;
            IPEndPoint serverEP = new IPEndPoint(address, port);
            tcpServer = new AsyncTcpServer(serverEP);
            tcpServer.DatagramReceived += TcpServer_DatagramReceived;
            tcpServer.ClientConnected += TcpServer_ClientConnected;
            tcpServer.ClientDisconnected += TcpServer_ClientDisconnected;
            tcpServer.ServertError += TcpServer_ServertError;
            tcpServer.Start(1);
        }
        public void CreatClientSocketAndConnected()
        {
            tcpClient.Close();
            tcpClient.Connect();
        }
        /// <summary>
        /// 模拟人开始按压
        /// </summary>
        public void StartModel()
        {
            tcpClient.Send(CommandM.Start);
        }
        public void StopModel()
        {
            tcpClient.Send(CommandM.Stop);
        }
        /// <summary>
        /// 客户端连接
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TcpServer_ClientConnected(object sender, TcpClientConnectedEventArgs e)
        {
            PadConnetState?.Invoke(e.TcpClient, true);           
            //ServerManager.Instance.AddText("有一个客户端连入服务器");
            //if (clientipe.Address.ToString() == padIPaddress)
            //{
            //}
            IPEndPoint clientipe = (IPEndPoint)e.TcpClient.RemoteEndPoint;
            Debug.Log("有一个客户端连入服务器:" + clientipe.Address.ToString());
        }

        /// <summary>
        /// 服务端断开连接
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TcpServer_ClientDisconnected(object sender, TcpClientDisconnectedEventArgs e)
        {
            IPEndPoint clientipe = (IPEndPoint)e.TcpClient.RemoteEndPoint;
            PadConnetState?.Invoke(e.TcpClient, false);
            //if (clientipe.Address.ToString() == padIPaddress)
            //{
            //    PadConnetState?.Invoke(e.TcpClient, false);
            //}
            TcpClientState clientState = tcpServer.ClientList.FirstOrDefault(item => item.TcpClient.Equals(e.TcpClient));
            if (clientState != null)
            {
                clientState.TcpClient.Shutdown(SocketShutdown.Both);
                clientState.TcpClient.Close();
                Debug.Log("有一个客户端和服务器断开连接");
                tcpServer.ClientList.Remove(clientState);
            }
        }
        /// <summary>
        /// 网络异常 断开pad
        /// </summary>
        /// <param name="tcpError"></param>
        private void TcpServer_ServertError(object sender, TcpClientNetErrowEventArgs  tcpError) {
            Debug.Log("平板断开连接");
            IPEndPoint clientipe = (IPEndPoint)tcpError.TcpSocket.RemoteEndPoint;
            PadConnetState?.Invoke(tcpError.TcpSocket, false);
        }
        private void TcpServer_ClientDisconnected(TcpClientState client) {
            PadConnetState?.Invoke(client.TcpClient, false);
            TcpClientState clientState = tcpServer.ClientList.FirstOrDefault(item => item.TcpClient.Equals(client.TcpClient));
            Debug.Log("有一个客户端和服务器断开连接" + ((IPEndPoint)client.TcpClient.RemoteEndPoint).Address);
            clientState.TcpClient.Close();
            //+"pad ip:" + ((IPEndPoint)clientState.TcpClient.RemoteEndPoint).Address
          
            tcpServer.ClientList.Remove(clientState);
        }

        /// <summary>
        /// 和模拟人服务器断开连接 事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TcpClient_ServerDisConnected(object sender, TcpServerDisconnectedEventArgs e)
        {
            BodyConnetState?.Invoke(e.Addresses, e.Port, false);
            //Loom.QueueOnMainThread(() => {
            //    ServerManager.Instance.AddText("已经和模拟人服务器断开连接");
            //});
        }


        /// <summary>
        /// 和模拟人服务器建立连接 事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TcpClient_ServerConnected(object sender, TcpServerConnectedEventArgs e)
        {

            BodyConnetState?.Invoke(e.Addresses, e.Port, true);
            Debug.Log("已经和模拟人服务器建立连接");
            //Loom.QueueOnMainThread(() => {
            //    ServerManager.Instance.AddText("已经和模拟人服务器建立连接");
            //});
            //if(BodyConnetState!=null) BodyConnetState.Invoke(e.Addresses, e.Port, true);
        }

        /// <summary>
        /// 接收模拟人数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TcpClient_DatagramReceive(object sender, TcpDatagramReceivedEventArgs<byte[]> e)
        {
            try
            {
                if (e.Datagram == null || e.Datagram.Length < 1) return;

                //string data = string.Empty;
                //for (int i = 0; i < e.Datagram.Length; i++)
                //    data += e.Datagram[i] + " ";
                //Loom.QueueOnMainThread(() => {
                //    ServerManager.Instance.SetModelAnimator(e.Datagram);
                //});
            }
            catch (Exception ex)
            {
                Debug.Log(ex);
            }
        }

        /// <summary>
        /// 服务端接收数据
        /// </summary>
        /// <param name="sender">客户端对象</param>
        /// <param name="e">bytes数据</param>
        private void TcpServer_DatagramReceived(object sender, TcpDatagramReceivedEventArgs<byte[]> e)
        {
           
            if (e.Datagram == null || e.Datagram.Length < 1 || e.TcpClient == null) return;
            byte[] data = e.Datagram;
            IPEndPoint clientipe = (IPEndPoint)e.TcpClient.RemoteEndPoint;
            dataBuffer.WriteBuffer(e.Datagram);
        }

        public void ClearPadClient() {
            var clients = tcpServer.ClientList;
            for (int i = 0; i < clients.Count; i++)
            {
                TcpServer_ClientDisconnected(clients[i]);
            }
        }

        

        
    }
}
